<html>
<head>
  <title>FFMPEG源码分析:I/O模块</title>
  <basefont face="微软雅黑" size="2" />
  <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
  <meta name="exporter-version" content="YXBJ Windows/604452 (zh-CN, DDL); Windows/10.0.0 (Win64); EDAMVersion=V2;"/>
  <meta name="content-class" content="yinxiang.markdown"/>
  <style>
    body, td {
      font-family: 微软雅黑;
      font-size: 10pt;
    }
  </style>
</head>
<body>
<a name="534"/>
<h1>FFMPEG源码分析:I/O模块</h1>

<div><span><div style="font-size: 14px; margin: 0; padding: 0; width: 100%;"><h1 style="line-height: 160%; box-sizing: content-box; font-weight: 700; font-size: 41px; border-bottom: 3px double #999; color: #000; margin-top: 14px;">【FFMPEG】源码分析：I/O模块</h1>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">参考链接：</p>
<ul style="line-height: 160%; box-sizing: content-box; display: block; list-style-type: disc; padding-left: 30px; margin: 6px 0 10px; color: #333;">
<li style="line-height: 160%; box-sizing: content-box; position: relative;">雷霄骅 <a href="https://blog.csdn.net/leixiaohua1020/article/details/84489473" style="line-height: 160%; box-sizing: content-box; text-decoration: underline; color: #5286bc;">FFmpeg架构之I/O模块分析</a></li>
</ul>
<h2 style="line-height: 160%; box-sizing: content-box; font-weight: 700; font-size: 34px; border-bottom: 1px solid #dbdbdb; color: #333;">概述</h2>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;"><code style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; color: #c1788b; padding: 4px 4px 2px 0; letter-spacing: -.3px;">ffmpeg</code>项目的数据<code style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; color: #c1788b; padding: 4px 4px 2px 0; letter-spacing: -.3px;">I/O</code>部分主要是在<code style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; color: #c1788b; padding: 4px 4px 2px 0; letter-spacing: -.3px;">libavformat</code>库中实现，某些对于内存的操作部分在<code style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; color: #c1788b; padding: 4px 4px 2px 0; letter-spacing: -.3px;">libavutil</code>库中。数据<code style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; color: #c1788b; padding: 4px 4px 2px 0; letter-spacing: -.3px;">I/O</code>是基于文件格式（<code style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; color: #c1788b; padding: 4px 4px 2px 0; letter-spacing: -.3px;">Format</code>）以及文件传输协议(<code style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; color: #c1788b; padding: 4px 4px 2px 0; letter-spacing: -.3px;">Protocol</code>)的，与具体的编解码标准无关。 <code style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; color: #c1788b; padding: 4px 4px 2px 0; letter-spacing: -.3px;">ffmpeg</code>工程转码时数据<code style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; color: #c1788b; padding: 4px 4px 2px 0; letter-spacing: -.3px;">I/O</code>层次关系如图所示：</p>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;"><img src="FFMPEG源码分析IO模块_files/【FFMPEG】转码数据IO流程.svg" type="image/svg+xml" data-filename="【FFMPEG】转码数据IO流程.svg"/></p>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">对于上面的数据<code style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; color: #c1788b; padding: 4px 4px 2px 0; letter-spacing: -.3px;">I/O</code>流程，具体可以用下面的例子来说明，我们从一个<code style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; color: #c1788b; padding: 4px 4px 2px 0; letter-spacing: -.3px;">http</code>服务器获取音视频数据，格式是<code style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; color: #c1788b; padding: 4px 4px 2px 0; letter-spacing: -.3px;">flv</code>的，需要通过转码后变成<code style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; color: #c1788b; padding: 4px 4px 2px 0; letter-spacing: -.3px;">avi</code>格式，然后通过<code style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; color: #c1788b; padding: 4px 4px 2px 0; letter-spacing: -.3px;">udp</code>协议进行发布。其过程就如下所示：</p>
<ul style="line-height: 160%; box-sizing: content-box; display: block; list-style-type: disc; padding-left: 30px; margin: 6px 0 10px; color: #333;">
<li style="line-height: 160%; box-sizing: content-box; position: relative;">读入<code style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; color: #c1788b; padding: 4px 4px 2px 0; letter-spacing: -.3px;">http</code>协议数据流，根据<code style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; color: #c1788b; padding: 4px 4px 2px 0; letter-spacing: -.3px;">http</code>协议获取真正的文件数据（去除无关报文信息）；</li>
<li style="line-height: 160%; box-sizing: content-box; position: relative;">根据<code style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; color: #c1788b; padding: 4px 4px 2px 0; letter-spacing: -.3px;">flv</code>格式对数据进行解封装；</li>
<li style="line-height: 160%; box-sizing: content-box; position: relative;">读取帧进行转码操作；</li>
<li style="line-height: 160%; box-sizing: content-box; position: relative;">按照目标格式<code style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; color: #c1788b; padding: 4px 4px 2px 0; letter-spacing: -.3px;">avi</code>进行封装；</li>
<li style="line-height: 160%; box-sizing: content-box; position: relative;">通过<code style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; color: #c1788b; padding: 4px 4px 2px 0; letter-spacing: -.3px;">udp</code>协议发送出去。</li>
</ul>
<h2 style="line-height: 160%; box-sizing: content-box; font-weight: 700; font-size: 34px; border-bottom: 1px solid #dbdbdb; color: #333;">相关数据结构</h2>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">在<code style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; color: #c1788b; padding: 4px 4px 2px 0; letter-spacing: -.3px;">libavformat</code>库中与数据<code style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; color: #c1788b; padding: 4px 4px 2px 0; letter-spacing: -.3px;">I/O</code>相关的数据结构主要有<code style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; color: #c1788b; padding: 4px 4px 2px 0; letter-spacing: -.3px;">URLProtocol</code>、<code style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; color: #c1788b; padding: 4px 4px 2px 0; letter-spacing: -.3px;">URLContext</code>、<code style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; color: #c1788b; padding: 4px 4px 2px 0; letter-spacing: -.3px;">AVIOContext</code>、<code style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; color: #c1788b; padding: 4px 4px 2px 0; letter-spacing: -.3px;">AVFormatContext</code>等，各结构之间的关系如图所示。<br/>
<img src="FFMPEG源码分析IO模块_files/【FFMPEG】IO模块数据结构.svg" type="image/svg+xml" data-filename="【FFMPEG】IO模块数据结构.svg"/></p>
<h3 style="line-height: 160%; box-sizing: content-box; font-weight: 700; font-size: 27px; color: #333;"><code style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; color: #c1788b; padding: 4px 4px 2px 0; letter-spacing: -.3px;">URLProtocol</code></h3>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">表示广义的输入文件，该结构体提供了很多的功能函数，每一种广义的输入文件（如：<code style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; color: #c1788b; padding: 4px 4px 2px 0; letter-spacing: -.3px;">file</code>、<code style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; color: #c1788b; padding: 4px 4px 2px 0; letter-spacing: -.3px;">pipe</code>、<code style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; color: #c1788b; padding: 4px 4px 2px 0; letter-spacing: -.3px;">tcp</code>、<code style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; color: #c1788b; padding: 4px 4px 2px 0; letter-spacing: -.3px;">rtp</code>等等）对应着一个<code style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; color: #c1788b; padding: 4px 4px 2px 0; letter-spacing: -.3px;">URLProtocol</code>结构，在<code style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; color: #c1788b; padding: 4px 4px 2px 0; letter-spacing: -.3px;">av_register_all()</code>中将该结构体初始化为一个链表，表头为<code style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; color: #c1788b; padding: 4px 4px 2px 0; letter-spacing: -.3px;">avio.c</code>里的<code style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; color: #c1788b; padding: 4px 4px 2px 0; letter-spacing: -.3px;">URLProtocol *first_protocol = NULL</code>；保存所有支持的输入文件协议，该结构体的定义如下：</p>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">typedef</span> <span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">struct</span> <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">URLProtocol</span> {</span>
    <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">const</span> <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">char</span> *name;
    <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">int</span>     (*url_open)( URLContext *h, <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">const</span> <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">char</span> *url, <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">int</span> flags);
    
    <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">int</span>     (*url_open2)(URLContext *h, <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">const</span> <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">char</span> *url, <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">int</span> flags, AVDictionary **options);
    <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">int</span>     (*url_accept)(URLContext *s, URLContext **c);
    <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">int</span>     (*url_handshake)(URLContext *c);

    <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">int</span>     (*url_read)( URLContext *h, <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">unsigned</span> <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">char</span> *buf, <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">int</span> <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">size</span>);
    <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">int</span>     (*url_write)(URLContext *h, <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">const</span> <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">unsigned</span> <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">char</span> *buf, <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">int</span> <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">size</span>);
    <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">int64_t</span> (*url_seek)( URLContext *h, <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">int64_t</span> pos, <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">int</span> whence);
    <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">int</span>     (*url_close)(URLContext *h);
    <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">int</span> (*url_read_pause)(URLContext *h, <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">int</span> pause);
    <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">int64_t</span> (*url_read_seek)(URLContext *h, <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">int</span> stream_index,
                             <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">int64_t</span> timestamp, <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">int</span> flags);
    <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">int</span> (*url_get_file_handle)(URLContext *h);
    <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">int</span> (*url_get_multi_file_handle)(URLContext *h, <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">int</span> **handles,
                                     <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">int</span> *numhandles);
    <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">int</span> (*url_get_short_seek)(URLContext *h);
    <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">int</span> (*url_shutdown)(URLContext *h, <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">int</span> flags);
    <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">const</span> AVClass *priv_data_class;
    <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">int</span> priv_data_size;
    <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">int</span> flags;
    <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">int</span> (*url_check)(URLContext *h, <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">int</span> mask);
    <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">int</span> (*url_open_dir)(URLContext *h);
    <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">int</span> (*url_read_dir)(URLContext *h, AVIODirEntry **next);
    <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">int</span> (*url_close_dir)(URLContext *h);
    <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">int</span> (*url_delete)(URLContext *h);
    <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">int</span> (*url_move)(URLContext *h_src, URLContext *h_dst);
    <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">const</span> <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">char</span> *default_whitelist;
} URLProtocol;
</code></pre>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">为了协议的统一管理，<code style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; color: #c1788b; padding: 4px 4px 2px 0; letter-spacing: -.3px;">ffmpeg</code>项目中将所有的用到的协议都存放在一个全局变量数组<code style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; color: #c1788b; padding: 4px 4px 2px 0; letter-spacing: -.3px;">url_protocols</code>中<code style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; color: #c1788b; padding: 4px 4px 2px 0; letter-spacing: -.3px;">URLProtocol</code>在各个具体的文件协议中有一个具体的实例，如在<code style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; color: #c1788b; padding: 4px 4px 2px 0; letter-spacing: -.3px;">file</code>协议中定义为：</p>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">const</span> URLProtocol ff_file_protocol = {
    .name                = <span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">&quot;file&quot;</span>,
    .url_open            = file_open,
    .url_read            = file_read,
    .url_write           = file_write,
    .url_seek            = file_seek,
    .url_close           = file_close,
    .url_get_file_handle = file_get_handle,
    .url_check           = file_check,
    .url_delete          = file_delete,
    .url_move            = file_move,
    .priv_data_size      = <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">sizeof</span>(FileContext),
    .priv_data_class     = &amp;file_class,
    .url_open_dir        = file_open_dir,
    .url_read_dir        = file_read_dir,
    .url_close_dir       = file_close_dir,
    .default_whitelist   = <span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">&quot;file,crypto,data&quot;</span>
};
</code></pre>
<blockquote style="line-height: 160%; box-sizing: content-box; margin: 15px 0; border-left: 4px solid #ddd; padding: 0 15px; color: #777;">
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333; margin-top: 0; margin-bottom: 0;">注意：在老版本的<code style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; color: #c1788b; padding: 4px 4px 2px 0; letter-spacing: -.3px;">FFMPEG</code>中，是将所有的<code style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; color: #c1788b; padding: 4px 4px 2px 0; letter-spacing: -.3px;">URLProtocol</code>实例都使用链表的方式来管理，所以在程序的启动的时候需要调用<code style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; color: #c1788b; padding: 4px 4px 2px 0; letter-spacing: -.3px;">av_register_all()</code>函数来将所有的<code style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; color: #c1788b; padding: 4px 4px 2px 0; letter-spacing: -.3px;">URLProtocol</code>实例都注册到对应的链表中。从<code style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; color: #c1788b; padding: 4px 4px 2px 0; letter-spacing: -.3px;">0694d87024</code>将这些注册函数丢弃。</p>
</blockquote>
<h3 style="line-height: 160%; box-sizing: content-box; font-weight: 700; font-size: 27px; color: #333;"><code style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; color: #c1788b; padding: 4px 4px 2px 0; letter-spacing: -.3px;">URLContext</code></h3>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;"><code style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; color: #c1788b; padding: 4px 4px 2px 0; letter-spacing: -.3px;">URLContext</code>提供了与当前打开的具体的文件协议（<code style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; color: #c1788b; padding: 4px 4px 2px 0; letter-spacing: -.3px;">URL</code>）相关数据的描述，在该结构中定义了指定当前<code style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; color: #c1788b; padding: 4px 4px 2px 0; letter-spacing: -.3px;">URL</code>（即<code style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; color: #c1788b; padding: 4px 4px 2px 0; letter-spacing: -.3px;">filename</code>项）所要用到的具体的<code style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; color: #c1788b; padding: 4px 4px 2px 0; letter-spacing: -.3px;">URLProtocol</code>，即：提供了一个在<code style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; color: #c1788b; padding: 4px 4px 2px 0; letter-spacing: -.3px;">URLprotocol</code>链表中找到具体项的依据，此外还有一些其它的标志性的信息，如<code style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; color: #c1788b; padding: 4px 4px 2px 0; letter-spacing: -.3px;">flags</code>，<code style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; color: #c1788b; padding: 4px 4px 2px 0; letter-spacing: -.3px;">is_streamed</code>等。它可以看成某一种协议的载体。其结构定义如下：</p>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">typedef</span> <span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">struct</span> <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">URLContext</span> {</span>
    <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">const</span> AVClass *av_class;    <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">/**&lt; information for av_log(). Set by url_open(). */</span>
    <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">const</span> <span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">struct</span> <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">URLProtocol</span> *<span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">prot</span>;</span>
    <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">void</span> *priv_data;
    <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">char</span> *filename;             <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">/**&lt; specified URL */</span>
    <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">int</span> flags;
    <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">int</span> max_packet_size;        <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">/**&lt; if non zero, the stream is packetized with this max packet size */</span>
    <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">int</span> is_streamed;            <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">/**&lt; true if streamed (no seek possible), default = false */</span>
    <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">int</span> is_connected;
    AVIOInterruptCB interrupt_callback;
    <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">int64_t</span> rw_timeout;         <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">/**&lt; maximum time to wait for (network) read/write operation completion, in mcs */</span>
    <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">const</span> <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">char</span> *protocol_whitelist;
    <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">const</span> <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">char</span> *protocol_blacklist;
    <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">int</span> min_packet_size;        <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">/**&lt; if non zero, the stream is packetized with this min packet size */</span>
} URLContext;
</code></pre>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">那么<code style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; color: #c1788b; padding: 4px 4px 2px 0; letter-spacing: -.3px;">ffmpeg</code>依据什么信息初始化<code style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; color: #c1788b; padding: 4px 4px 2px 0; letter-spacing: -.3px;">URLContext</code>？然后又是如何初始化<code style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; color: #c1788b; padding: 4px 4px 2px 0; letter-spacing: -.3px;">URLContext</code>的呢？在打开一个<code style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; color: #c1788b; padding: 4px 4px 2px 0; letter-spacing: -.3px;">URL</code>时，全局函数<code style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; color: #c1788b; padding: 4px 4px 2px 0; letter-spacing: -.3px;">ffurl_open</code>会根据<code style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; color: #c1788b; padding: 4px 4px 2px 0; letter-spacing: -.3px;">filename</code>的前缀信息来确定<code style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; color: #c1788b; padding: 4px 4px 2px 0; letter-spacing: -.3px;">URL</code>所使用的具体协议，并为该协议分配好资源，再调用<code style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; color: #c1788b; padding: 4px 4px 2px 0; letter-spacing: -.3px;">ffurl_connect</code>函数打开具体协议，即调用协议的<code style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; color: #c1788b; padding: 4px 4px 2px 0; letter-spacing: -.3px;">url_open</code>，调用关系如下：</p>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;"><span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">int</span> <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">avformat_open_input</span><span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">(AVFormatContext **ps, <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">const</span> <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">char</span> *filename, 
                        <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">const</span> AVInputFormat *fmt, AVDictionary **options)</span></span>;
<span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">static</span> <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">int</span> <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">init_input</span><span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">(AVFormatContext *s, <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">const</span> <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">char</span> *filename, AVDictionary **options)</span></span>;
<span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">static</span> <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">int</span> <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">io_open_default</span><span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">(AVFormatContext *s, AVIOContext **pb, 
                        <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">const</span> <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">char</span> *url, <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">int</span> flags, AVDictionary **options)</span></span>;
<span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">int</span> <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">ffio_open_whitelist</span><span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">(AVIOContext **s, <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">const</span> <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">char</span> *filename, <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">int</span> flags,
                         <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">const</span> AVIOInterruptCB *int_cb, AVDictionary **options,
                         <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">const</span> <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">char</span> *whitelist, <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">const</span> <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">char</span> *blacklist
                        )</span></span>;
<span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">int</span> <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">ffurl_open_whitelist</span><span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">(URLContext **puc, <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">const</span> <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">char</span> *filename, <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">int</span> flags,
                         <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">const</span> AVIOInterruptCB *int_cb, AVDictionary **options,
                         <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">const</span> <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">char</span> *whitelist, <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">const</span> <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">char</span>* blacklist,
                         URLContext *parent)</span></span>;
<span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">int</span> <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">ffurl_alloc</span><span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">(URLContext **puc, <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">const</span> <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">char</span> *filename, <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">int</span> flags,
                <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">const</span> AVIOInterruptCB *int_cb)</span></span>;
<span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">static</span> <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">int</span> <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">url_alloc_for_protocol</span><span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">(URLContext **puc, <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">const</span> URLProtocol *up,
                                  <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">const</span> <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">char</span> *filename, <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">int</span> flags,
                                  <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">const</span> AVIOInterruptCB *int_cb)</span></span>;
</code></pre>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;"><img src="FFMPEG源码分析IO模块_files/【FFMPEG】av_open_input_file.svg" type="image/svg+xml" data-filename="【FFMPEG】av_open_input_file.svg"/></p>
</div><center style="display:none !important;visibility:collapse !important;height:0 !important;white-space:nowrap;width:100%;overflow:hidden">%23%20%E3%80%90FFMPEG%E3%80%91%E6%BA%90%E7%A0%81%E5%88%86%E6%9E%90%EF%BC%9AI%2FO%E6%A8%A1%E5%9D%97%0A%0A%E5%8F%82%E8%80%83%E9%93%BE%E6%8E%A5%EF%BC%9A%0A-%20%E9%9B%B7%E9%9C%84%E9%AA%85%20%5BFFmpeg%E6%9E%B6%E6%9E%84%E4%B9%8BI%2FO%E6%A8%A1%E5%9D%97%E5%88%86%E6%9E%90%5D(https%3A%2F%2Fblog.csdn.net%2Fleixiaohua1020%2Farticle%2Fdetails%2F84489473)%0A%0A%23%23%20%E6%A6%82%E8%BF%B0%0A%0A%60ffmpeg%60%E9%A1%B9%E7%9B%AE%E7%9A%84%E6%95%B0%E6%8D%AE%60I%2FO%60%E9%83%A8%E5%88%86%E4%B8%BB%E8%A6%81%E6%98%AF%E5%9C%A8%60libavformat%60%E5%BA%93%E4%B8%AD%E5%AE%9E%E7%8E%B0%EF%BC%8C%E6%9F%90%E4%BA%9B%E5%AF%B9%E4%BA%8E%E5%86%85%E5%AD%98%E7%9A%84%E6%93%8D%E4%BD%9C%E9%83%A8%E5%88%86%E5%9C%A8%60libavutil%60%E5%BA%93%E4%B8%AD%E3%80%82%E6%95%B0%E6%8D%AE%60I%2FO%60%E6%98%AF%E5%9F%BA%E4%BA%8E%E6%96%87%E4%BB%B6%E6%A0%BC%E5%BC%8F%EF%BC%88%60Format%60%EF%BC%89%E4%BB%A5%E5%8F%8A%E6%96%87%E4%BB%B6%E4%BC%A0%E8%BE%93%E5%8D%8F%E8%AE%AE(%60Protocol%60)%E7%9A%84%EF%BC%8C%E4%B8%8E%E5%85%B7%E4%BD%93%E7%9A%84%E7%BC%96%E8%A7%A3%E7%A0%81%E6%A0%87%E5%87%86%E6%97%A0%E5%85%B3%E3%80%82%20%60ffmpeg%60%E5%B7%A5%E7%A8%8B%E8%BD%AC%E7%A0%81%E6%97%B6%E6%95%B0%E6%8D%AE%60I%2FO%60%E5%B1%82%E6%AC%A1%E5%85%B3%E7%B3%BB%E5%A6%82%E5%9B%BE%E6%89%80%E7%A4%BA%EF%BC%9A%0A%0A%0A!%5B934f22d22f392ec0cca7a6af500249fb.svg%2Bxml%5D(en-resource%3A%2F%2Fdatabase%2F542%3A1)%0A%0A%0A%0A%E5%AF%B9%E4%BA%8E%E4%B8%8A%E9%9D%A2%E7%9A%84%E6%95%B0%E6%8D%AE%60I%2FO%60%E6%B5%81%E7%A8%8B%EF%BC%8C%E5%85%B7%E4%BD%93%E5%8F%AF%E4%BB%A5%E7%94%A8%E4%B8%8B%E9%9D%A2%E7%9A%84%E4%BE%8B%E5%AD%90%E6%9D%A5%E8%AF%B4%E6%98%8E%EF%BC%8C%E6%88%91%E4%BB%AC%E4%BB%8E%E4%B8%80%E4%B8%AA%60http%60%E6%9C%8D%E5%8A%A1%E5%99%A8%E8%8E%B7%E5%8F%96%E9%9F%B3%E8%A7%86%E9%A2%91%E6%95%B0%E6%8D%AE%EF%BC%8C%E6%A0%BC%E5%BC%8F%E6%98%AF%60flv%60%E7%9A%84%EF%BC%8C%E9%9C%80%E8%A6%81%E9%80%9A%E8%BF%87%E8%BD%AC%E7%A0%81%E5%90%8E%E5%8F%98%E6%88%90%60avi%60%E6%A0%BC%E5%BC%8F%EF%BC%8C%E7%84%B6%E5%90%8E%E9%80%9A%E8%BF%87%60udp%60%E5%8D%8F%E8%AE%AE%E8%BF%9B%E8%A1%8C%E5%8F%91%E5%B8%83%E3%80%82%E5%85%B6%E8%BF%87%E7%A8%8B%E5%B0%B1%E5%A6%82%E4%B8%8B%E6%89%80%E7%A4%BA%EF%BC%9A%0A-%20%E8%AF%BB%E5%85%A5%60http%60%E5%8D%8F%E8%AE%AE%E6%95%B0%E6%8D%AE%E6%B5%81%EF%BC%8C%E6%A0%B9%E6%8D%AE%60http%60%E5%8D%8F%E8%AE%AE%E8%8E%B7%E5%8F%96%E7%9C%9F%E6%AD%A3%E7%9A%84%E6%96%87%E4%BB%B6%E6%95%B0%E6%8D%AE%EF%BC%88%E5%8E%BB%E9%99%A4%E6%97%A0%E5%85%B3%E6%8A%A5%E6%96%87%E4%BF%A1%E6%81%AF%EF%BC%89%EF%BC%9B%0A-%20%E6%A0%B9%E6%8D%AE%60flv%60%E6%A0%BC%E5%BC%8F%E5%AF%B9%E6%95%B0%E6%8D%AE%E8%BF%9B%E8%A1%8C%E8%A7%A3%E5%B0%81%E8%A3%85%EF%BC%9B%0A-%20%E8%AF%BB%E5%8F%96%E5%B8%A7%E8%BF%9B%E8%A1%8C%E8%BD%AC%E7%A0%81%E6%93%8D%E4%BD%9C%EF%BC%9B%0A-%20%E6%8C%89%E7%85%A7%E7%9B%AE%E6%A0%87%E6%A0%BC%E5%BC%8F%60avi%60%E8%BF%9B%E8%A1%8C%E5%B0%81%E8%A3%85%EF%BC%9B%0A-%20%E9%80%9A%E8%BF%87%60udp%60%E5%8D%8F%E8%AE%AE%E5%8F%91%E9%80%81%E5%87%BA%E5%8E%BB%E3%80%82%0A%0A%23%23%20%E7%9B%B8%E5%85%B3%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%0A%0A%0A%E5%9C%A8%60libavformat%60%E5%BA%93%E4%B8%AD%E4%B8%8E%E6%95%B0%E6%8D%AE%60I%2FO%60%E7%9B%B8%E5%85%B3%E7%9A%84%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E4%B8%BB%E8%A6%81%E6%9C%89%60URLProtocol%60%E3%80%81%60URLContext%60%E3%80%81%60AVIOContext%60%E3%80%81%60AVFormatContext%60%E7%AD%89%EF%BC%8C%E5%90%84%E7%BB%93%E6%9E%84%E4%B9%8B%E9%97%B4%E7%9A%84%E5%85%B3%E7%B3%BB%E5%A6%82%E5%9B%BE%E6%89%80%E7%A4%BA%E3%80%82%0A!%5Bad0a9a2de751489a77b58d1fe07ed6cf.svg%2Bxml%5D(en-resource%3A%2F%2Fdatabase%2F540%3A1)%0A%0A%23%23%23%20%60URLProtocol%60%0A%0A%0A%E8%A1%A8%E7%A4%BA%E5%B9%BF%E4%B9%89%E7%9A%84%E8%BE%93%E5%85%A5%E6%96%87%E4%BB%B6%EF%BC%8C%E8%AF%A5%E7%BB%93%E6%9E%84%E4%BD%93%E6%8F%90%E4%BE%9B%E4%BA%86%E5%BE%88%E5%A4%9A%E7%9A%84%E5%8A%9F%E8%83%BD%E5%87%BD%E6%95%B0%EF%BC%8C%E6%AF%8F%E4%B8%80%E7%A7%8D%E5%B9%BF%E4%B9%89%E7%9A%84%E8%BE%93%E5%85%A5%E6%96%87%E4%BB%B6%EF%BC%88%E5%A6%82%EF%BC%9A%60file%60%E3%80%81%60pipe%60%E3%80%81%60tcp%60%E3%80%81%60rtp%60%E7%AD%89%E7%AD%89%EF%BC%89%E5%AF%B9%E5%BA%94%E7%9D%80%E4%B8%80%E4%B8%AA%60URLProtocol%60%E7%BB%93%E6%9E%84%EF%BC%8C%E5%9C%A8%60av_register_all()%60%E4%B8%AD%E5%B0%86%E8%AF%A5%E7%BB%93%E6%9E%84%E4%BD%93%E5%88%9D%E5%A7%8B%E5%8C%96%E4%B8%BA%E4%B8%80%E4%B8%AA%E9%93%BE%E8%A1%A8%EF%BC%8C%E8%A1%A8%E5%A4%B4%E4%B8%BA%60avio.c%60%E9%87%8C%E7%9A%84%60URLProtocol%20*first_protocol%20%3D%20NULL%60%EF%BC%9B%E4%BF%9D%E5%AD%98%E6%89%80%E6%9C%89%E6%94%AF%E6%8C%81%E7%9A%84%E8%BE%93%E5%85%A5%E6%96%87%E4%BB%B6%E5%8D%8F%E8%AE%AE%EF%BC%8C%E8%AF%A5%E7%BB%93%E6%9E%84%E4%BD%93%E7%9A%84%E5%AE%9A%E4%B9%89%E5%A6%82%E4%B8%8B%EF%BC%9A%0A%60%60%60c%2B%2B%0Atypedef%20struct%20URLProtocol%20%7B%0A%20%20%20%20const%20char%20*name%3B%0A%20%20%20%20int%20%20%20%20%20(*url_open)(%20URLContext%20*h%2C%20const%20char%20*url%2C%20int%20flags)%3B%0A%20%20%20%20%0A%20%20%20%20int%20%20%20%20%20(*url_open2)(URLContext%20*h%2C%20const%20char%20*url%2C%20int%20flags%2C%20AVDictionary%20**options)%3B%0A%20%20%20%20int%20%20%20%20%20(*url_accept)(URLContext%20*s%2C%20URLContext%20**c)%3B%0A%20%20%20%20int%20%20%20%20%20(*url_handshake)(URLContext%20*c)%3B%0A%0A%20%20%20%20int%20%20%20%20%20(*url_read)(%20URLContext%20*h%2C%20unsigned%20char%20*buf%2C%20int%20size)%3B%0A%20%20%20%20int%20%20%20%20%20(*url_write)(URLContext%20*h%2C%20const%20unsigned%20char%20*buf%2C%20int%20size)%3B%0A%20%20%20%20int64_t%20(*url_seek)(%20URLContext%20*h%2C%20int64_t%20pos%2C%20int%20whence)%3B%0A%20%20%20%20int%20%20%20%20%20(*url_close)(URLContext%20*h)%3B%0A%20%20%20%20int%20(*url_read_pause)(URLContext%20*h%2C%20int%20pause)%3B%0A%20%20%20%20int64_t%20(*url_read_seek)(URLContext%20*h%2C%20int%20stream_index%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20int64_t%20timestamp%2C%20int%20flags)%3B%0A%20%20%20%20int%20(*url_get_file_handle)(URLContext%20*h)%3B%0A%20%20%20%20int%20(*url_get_multi_file_handle)(URLContext%20*h%2C%20int%20**handles%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20int%20*numhandles)%3B%0A%20%20%20%20int%20(*url_get_short_seek)(URLContext%20*h)%3B%0A%20%20%20%20int%20(*url_shutdown)(URLContext%20*h%2C%20int%20flags)%3B%0A%20%20%20%20const%20AVClass%20*priv_data_class%3B%0A%20%20%20%20int%20priv_data_size%3B%0A%20%20%20%20int%20flags%3B%0A%20%20%20%20int%20(*url_check)(URLContext%20*h%2C%20int%20mask)%3B%0A%20%20%20%20int%20(*url_open_dir)(URLContext%20*h)%3B%0A%20%20%20%20int%20(*url_read_dir)(URLContext%20*h%2C%20AVIODirEntry%20**next)%3B%0A%20%20%20%20int%20(*url_close_dir)(URLContext%20*h)%3B%0A%20%20%20%20int%20(*url_delete)(URLContext%20*h)%3B%0A%20%20%20%20int%20(*url_move)(URLContext%20*h_src%2C%20URLContext%20*h_dst)%3B%0A%20%20%20%20const%20char%20*default_whitelist%3B%0A%7D%20URLProtocol%3B%0A%60%60%60%0A%0A%E4%B8%BA%E4%BA%86%E5%8D%8F%E8%AE%AE%E7%9A%84%E7%BB%9F%E4%B8%80%E7%AE%A1%E7%90%86%EF%BC%8C%60ffmpeg%60%E9%A1%B9%E7%9B%AE%E4%B8%AD%E5%B0%86%E6%89%80%E6%9C%89%E7%9A%84%E7%94%A8%E5%88%B0%E7%9A%84%E5%8D%8F%E8%AE%AE%E9%83%BD%E5%AD%98%E6%94%BE%E5%9C%A8%E4%B8%80%E4%B8%AA%E5%85%A8%E5%B1%80%E5%8F%98%E9%87%8F%E6%95%B0%E7%BB%84%60url_protocols%60%E4%B8%AD%60URLProtocol%60%E5%9C%A8%E5%90%84%E4%B8%AA%E5%85%B7%E4%BD%93%E7%9A%84%E6%96%87%E4%BB%B6%E5%8D%8F%E8%AE%AE%E4%B8%AD%E6%9C%89%E4%B8%80%E4%B8%AA%E5%85%B7%E4%BD%93%E7%9A%84%E5%AE%9E%E4%BE%8B%EF%BC%8C%E5%A6%82%E5%9C%A8%60file%60%E5%8D%8F%E8%AE%AE%E4%B8%AD%E5%AE%9A%E4%B9%89%E4%B8%BA%EF%BC%9A%0A%60%60%60c%2B%2B%0Aconst%20URLProtocol%20ff_file_protocol%20%3D%20%7B%0A%20%20%20%20.name%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3D%20%22file%22%2C%0A%20%20%20%20.url_open%20%20%20%20%20%20%20%20%20%20%20%20%3D%20file_open%2C%0A%20%20%20%20.url_read%20%20%20%20%20%20%20%20%20%20%20%20%3D%20file_read%2C%0A%20%20%20%20.url_write%20%20%20%20%20%20%20%20%20%20%20%3D%20file_write%2C%0A%20%20%20%20.url_seek%20%20%20%20%20%20%20%20%20%20%20%20%3D%20file_seek%2C%0A%20%20%20%20.url_close%20%20%20%20%20%20%20%20%20%20%20%3D%20file_close%2C%0A%20%20%20%20.url_get_file_handle%20%3D%20file_get_handle%2C%0A%20%20%20%20.url_check%20%20%20%20%20%20%20%20%20%20%20%3D%20file_check%2C%0A%20%20%20%20.url_delete%20%20%20%20%20%20%20%20%20%20%3D%20file_delete%2C%0A%20%20%20%20.url_move%20%20%20%20%20%20%20%20%20%20%20%20%3D%20file_move%2C%0A%20%20%20%20.priv_data_size%20%20%20%20%20%20%3D%20sizeof(FileContext)%2C%0A%20%20%20%20.priv_data_class%20%20%20%20%20%3D%20%26file_class%2C%0A%20%20%20%20.url_open_dir%20%20%20%20%20%20%20%20%3D%20file_open_dir%2C%0A%20%20%20%20.url_read_dir%20%20%20%20%20%20%20%20%3D%20file_read_dir%2C%0A%20%20%20%20.url_close_dir%20%20%20%20%20%20%20%3D%20file_close_dir%2C%0A%20%20%20%20.default_whitelist%20%20%20%3D%20%22file%2Ccrypto%2Cdata%22%0A%7D%3B%0A%60%60%60%0A%0A%3E%20%E6%B3%A8%E6%84%8F%EF%BC%9A%E5%9C%A8%E8%80%81%E7%89%88%E6%9C%AC%E7%9A%84%60FFMPEG%60%E4%B8%AD%EF%BC%8C%E6%98%AF%E5%B0%86%E6%89%80%E6%9C%89%E7%9A%84%60URLProtocol%60%E5%AE%9E%E4%BE%8B%E9%83%BD%E4%BD%BF%E7%94%A8%E9%93%BE%E8%A1%A8%E7%9A%84%E6%96%B9%E5%BC%8F%E6%9D%A5%E7%AE%A1%E7%90%86%EF%BC%8C%E6%89%80%E4%BB%A5%E5%9C%A8%E7%A8%8B%E5%BA%8F%E7%9A%84%E5%90%AF%E5%8A%A8%E7%9A%84%E6%97%B6%E5%80%99%E9%9C%80%E8%A6%81%E8%B0%83%E7%94%A8%60av_register_all()%60%E5%87%BD%E6%95%B0%E6%9D%A5%E5%B0%86%E6%89%80%E6%9C%89%E7%9A%84%60URLProtocol%60%E5%AE%9E%E4%BE%8B%E9%83%BD%E6%B3%A8%E5%86%8C%E5%88%B0%E5%AF%B9%E5%BA%94%E7%9A%84%E9%93%BE%E8%A1%A8%E4%B8%AD%E3%80%82%E4%BB%8E%600694d87024%60%E5%B0%86%E8%BF%99%E4%BA%9B%E6%B3%A8%E5%86%8C%E5%87%BD%E6%95%B0%E4%B8%A2%E5%BC%83%E3%80%82%0A%0A%23%23%23%20%60URLContext%60%0A%0A%0A%60URLContext%60%E6%8F%90%E4%BE%9B%E4%BA%86%E4%B8%8E%E5%BD%93%E5%89%8D%E6%89%93%E5%BC%80%E7%9A%84%E5%85%B7%E4%BD%93%E7%9A%84%E6%96%87%E4%BB%B6%E5%8D%8F%E8%AE%AE%EF%BC%88%60URL%60%EF%BC%89%E7%9B%B8%E5%85%B3%E6%95%B0%E6%8D%AE%E7%9A%84%E6%8F%8F%E8%BF%B0%EF%BC%8C%E5%9C%A8%E8%AF%A5%E7%BB%93%E6%9E%84%E4%B8%AD%E5%AE%9A%E4%B9%89%E4%BA%86%E6%8C%87%E5%AE%9A%E5%BD%93%E5%89%8D%60URL%60%EF%BC%88%E5%8D%B3%60filename%60%E9%A1%B9%EF%BC%89%E6%89%80%E8%A6%81%E7%94%A8%E5%88%B0%E7%9A%84%E5%85%B7%E4%BD%93%E7%9A%84%60URLProtocol%60%EF%BC%8C%E5%8D%B3%EF%BC%9A%E6%8F%90%E4%BE%9B%E4%BA%86%E4%B8%80%E4%B8%AA%E5%9C%A8%60URLprotocol%60%E9%93%BE%E8%A1%A8%E4%B8%AD%E6%89%BE%E5%88%B0%E5%85%B7%E4%BD%93%E9%A1%B9%E7%9A%84%E4%BE%9D%E6%8D%AE%EF%BC%8C%E6%AD%A4%E5%A4%96%E8%BF%98%E6%9C%89%E4%B8%80%E4%BA%9B%E5%85%B6%E5%AE%83%E7%9A%84%E6%A0%87%E5%BF%97%E6%80%A7%E7%9A%84%E4%BF%A1%E6%81%AF%EF%BC%8C%E5%A6%82%60flags%60%EF%BC%8C%60is_streamed%60%E7%AD%89%E3%80%82%E5%AE%83%E5%8F%AF%E4%BB%A5%E7%9C%8B%E6%88%90%E6%9F%90%E4%B8%80%E7%A7%8D%E5%8D%8F%E8%AE%AE%E7%9A%84%E8%BD%BD%E4%BD%93%E3%80%82%E5%85%B6%E7%BB%93%E6%9E%84%E5%AE%9A%E4%B9%89%E5%A6%82%E4%B8%8B%EF%BC%9A%0A%60%60%60c%2B%2B%0Atypedef%20struct%20URLContext%20%7B%0A%20%20%20%20const%20AVClass%20*av_class%3B%20%20%20%20%2F**%3C%20information%20for%20av_log().%20Set%20by%20url_open().%20*%2F%0A%20%20%20%20const%20struct%20URLProtocol%20*prot%3B%0A%20%20%20%20void%20*priv_data%3B%0A%20%20%20%20char%20*filename%3B%20%20%20%20%20%20%20%20%20%20%20%20%20%2F**%3C%20specified%20URL%20*%2F%0A%20%20%20%20int%20flags%3B%0A%20%20%20%20int%20max_packet_size%3B%20%20%20%20%20%20%20%20%2F**%3C%20if%20non%20zero%2C%20the%20stream%20is%20packetized%20with%20this%20max%20packet%20size%20*%2F%0A%20%20%20%20int%20is_streamed%3B%20%20%20%20%20%20%20%20%20%20%20%20%2F**%3C%20true%20if%20streamed%20(no%20seek%20possible)%2C%20default%20%3D%20false%20*%2F%0A%20%20%20%20int%20is_connected%3B%0A%20%20%20%20AVIOInterruptCB%20interrupt_callback%3B%0A%20%20%20%20int64_t%20rw_timeout%3B%20%20%20%20%20%20%20%20%20%2F**%3C%20maximum%20time%20to%20wait%20for%20(network)%20read%2Fwrite%20operation%20completion%2C%20in%20mcs%20*%2F%0A%20%20%20%20const%20char%20*protocol_whitelist%3B%0A%20%20%20%20const%20char%20*protocol_blacklist%3B%0A%20%20%20%20int%20min_packet_size%3B%20%20%20%20%20%20%20%20%2F**%3C%20if%20non%20zero%2C%20the%20stream%20is%20packetized%20with%20this%20min%20packet%20size%20*%2F%0A%7D%20URLContext%3B%0A%60%60%60%0A%0A%E9%82%A3%E4%B9%88%60ffmpeg%60%E4%BE%9D%E6%8D%AE%E4%BB%80%E4%B9%88%E4%BF%A1%E6%81%AF%E5%88%9D%E5%A7%8B%E5%8C%96%60URLContext%60%EF%BC%9F%E7%84%B6%E5%90%8E%E5%8F%88%E6%98%AF%E5%A6%82%E4%BD%95%E5%88%9D%E5%A7%8B%E5%8C%96%60URLContext%60%E7%9A%84%E5%91%A2%EF%BC%9F%E5%9C%A8%E6%89%93%E5%BC%80%E4%B8%80%E4%B8%AA%60URL%60%E6%97%B6%EF%BC%8C%E5%85%A8%E5%B1%80%E5%87%BD%E6%95%B0%60ffurl_open%60%E4%BC%9A%E6%A0%B9%E6%8D%AE%60filename%60%E7%9A%84%E5%89%8D%E7%BC%80%E4%BF%A1%E6%81%AF%E6%9D%A5%E7%A1%AE%E5%AE%9A%60URL%60%E6%89%80%E4%BD%BF%E7%94%A8%E7%9A%84%E5%85%B7%E4%BD%93%E5%8D%8F%E8%AE%AE%EF%BC%8C%E5%B9%B6%E4%B8%BA%E8%AF%A5%E5%8D%8F%E8%AE%AE%E5%88%86%E9%85%8D%E5%A5%BD%E8%B5%84%E6%BA%90%EF%BC%8C%E5%86%8D%E8%B0%83%E7%94%A8%60ffurl_connect%60%E5%87%BD%E6%95%B0%E6%89%93%E5%BC%80%E5%85%B7%E4%BD%93%E5%8D%8F%E8%AE%AE%EF%BC%8C%E5%8D%B3%E8%B0%83%E7%94%A8%E5%8D%8F%E8%AE%AE%E7%9A%84%60url_open%60%EF%BC%8C%E8%B0%83%E7%94%A8%E5%85%B3%E7%B3%BB%E5%A6%82%E4%B8%8B%EF%BC%9A%0A%60%60%60c%2B%2B%0Aint%20avformat_open_input(AVFormatContext%20**ps%2C%20const%20char%20*filename%2C%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20AVInputFormat%20*fmt%2C%20AVDictionary%20**options)%3B%0Astatic%20int%20init_input(AVFormatContext%20*s%2C%20const%20char%20*filename%2C%20AVDictionary%20**options)%3B%0Astatic%20int%20io_open_default(AVFormatContext%20*s%2C%20AVIOContext%20**pb%2C%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20char%20*url%2C%20int%20flags%2C%20AVDictionary%20**options)%3B%0Aint%20ffio_open_whitelist(AVIOContext%20**s%2C%20const%20char%20*filename%2C%20int%20flags%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20AVIOInterruptCB%20*int_cb%2C%20AVDictionary%20**options%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20char%20*whitelist%2C%20const%20char%20*blacklist%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20)%3B%0Aint%20ffurl_open_whitelist(URLContext%20**puc%2C%20const%20char%20*filename%2C%20int%20flags%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20AVIOInterruptCB%20*int_cb%2C%20AVDictionary%20**options%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20char%20*whitelist%2C%20const%20char*%20blacklist%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20URLContext%20*parent)%3B%0Aint%20ffurl_alloc(URLContext%20**puc%2C%20const%20char%20*filename%2C%20int%20flags%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20AVIOInterruptCB%20*int_cb)%3B%0Astatic%20int%20url_alloc_for_protocol(URLContext%20**puc%2C%20const%20URLProtocol%20*up%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20char%20*filename%2C%20int%20flags%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20AVIOInterruptCB%20*int_cb)%3B%0A%60%60%60%0A%0A!%5Bd48e8ff5e23e424cd703472d9c674273.svg%2Bxml%5D(en-resource%3A%2F%2Fdatabase%2F544%3A0)%0A</center></span>
</div></body></html> 